Using the tangle exteriors, we can create branching sets of surgeries on the two knots K1 and K2. In this notebook, we verify these branching sets and build braid words of these that we can send to KnotJob and compute their Khovanov homologies from which we can read-off Watson's kappa invariant.

In [1]:

    import snappy

    def double_branched_cover(link):
        """
        Returns the double branched cover of the link.
        """
        L=link.copy()
        for i in range(L.num_cusps()):
            L.dehn_fill((2,0),i)
        for cov in L.covers(2):
            if (2.0, 0.0) not in cov.cusp_info('filling'):
                return cov

    def all_positive(manifold):
        '''
        Checks if the solution type of a triangulation is positive.
        '''
        return manifold.solution_type() == 'all tetrahedra positively oriented'

    def find_positive_triangulations(manifold,number=1,tries=100):
        '''
        Searches for one triangulation with a positive solution type.
        (Or if number is set to a different value also for different such triangulations.)
        '''
        M = manifold.copy()
        pos_triangulations=[]
        for i in range(tries):
            if all_positive(M):
                pos_triangulations.append(M)
                if len(pos_triangulations)==number:
                    return pos_triangulations
                break
            M.randomize()
        for d in M.dual_curves(max_segments=500):
            X = M.drill(d)
            X = X.filled_triangulation()
            X.dehn_fill((1,0),-1)
            for i in range(tries):
                if all_positive(X):
                    pos_triangulations.append(X)
                    if len(pos_triangulations)==number:
                        return pos_triangulations
                    break
                X.randomize()

        # In the closed case, here is another trick.
        if all(not c for c in M.cusp_info('is_complete')):
            for i in range(tries):
                # Drills out a random edge
                X = M.__class__(M.filled_triangulation())
                if all_positive(X):
                    pos_triangulations.append(X)
                    if len(pos_triangulations)==number:
                        return pos_triangulations
                break
                M.randomize()
        return pos_triangulations

    def better_is_isometric_to(X,Y,return_isometries=False,index=100,try_hard=False):
        """
        Returns True if X and Y are isometric.
        Returns False if X and Y have different homologies.
         """
        if return_isometries==False:
            w='unclear'
            if X.homology()!=Y.homology():
                return False
            for i in (0,index):
                try:
                    w=X.is_isometric_to(Y)
                except (RuntimeError,snappy.SnapPeaFatalError):
                    pass
                if w==True:
                    return w
                X.randomize()
                Y.randomize()
                i=i+1
            if try_hard:
                pos_triang_X=find_positive_triangulations(X,number=1,tries=index)
                pos_triang_Y=find_positive_triangulations(Y,number=1,tries=index)
                for X in pos_triang_X:
                    for Y in pos_triang_Y:
                        w=better_is_isometric_to(X,Y,index=100,try_hard=False)
                        if w==True:
                            return w
            return 'unclear'
        if return_isometries==True:
            w=False
            if X.homology()!=Y.homology():
                return []
            for i in (0,index):
                try:
                    w=X.is_isometric_to(Y,return_isometries)
                except (RuntimeError,snappy.SnapPeaFatalError):
                    pass
                if w!=False:
                    return w
                X.randomize()
                Y.randomize()
                i=i+1
            if try_hard:
                pos_triang_X=find_positive_triangulations(X,number=10,tries=index)
                pos_triang_Y=find_positive_triangulations(Y,number=10,tries=index)
                for X in pos_triang_X:
                    for Y in pos_triang_Y:
                        w=better_is_isometric_to(X,Y,return_isometries,index=100,try_hard=False)
                        if w!=False:
                            return w
            return []

    import regina

    def to_regina(data):
        '''
        This function was written by Dunfield.
        It sends a SnapPy triangulation to regina.
        '''
        if hasattr(data, '_to_string'):
            data = data._to_string()
        if isinstance(data, str):
            if data.find('(') > -1:
                data = closed_isosigs(data)[0]
            return regina.Triangulation3(data)
        assert isinstance(data, regina.Triangulation3)
        return data

    def display1(sig, tri):
        signatures1.append(sig)
        return False

    def display2(sig, tri):
        signatures2.append(sig)
        return False

    def search_for_combinatorial_equivalence(M,N,index_M=1,index_N=1):
        '''
        Takes as input two snappy triangulations, transforms them to regina and searches through the pachner graph for an
        equivalence.
        '''
        F1=M.filled_triangulation()
        F2=N.filled_triangulation()
        T1=to_regina(F1)
        T2=to_regina(F2)
        T1.simplifyExhaustive()
        T2.simplifyExhaustive()
        global signatures1
        signatures1=[]
        global signatures2
        signatures2=[]
        T1.retriangulate(index_M,1,display1)
        T2.retriangulate(index_N,1,display2)
        for s1 in signatures1:
            for s2 in signatures2:
                if s1==s2:
                    return True
        return False

    import string

    def braid_word_to_letters(word):
        '''Returns an alphabetical describtion of the braid word.'''
        upper=list(string.ascii_uppercase)
        lower=list(string.ascii_lowercase)
        stringword=''
        for x in word:
            for letter in lower:
                if x==ord(letter) - 96:
                    stringword=stringword+letter
                    break
            for letter in upper:
                if -x==ord(letter) - 64:
                    stringword=stringword+letter
                    break
        return stringword

In [2]:

    branching_sets=[[['t09847','K8_201'],
    [[(-22,1),[-1, 2, -3, -4, -5, 6, 5, -4, 3, -2, 4, 1, -3, 5, -6, -7, -6, -5, 4, -3, -2, -3, -4, 5, -4, 6, 3, 7, -4, -5, -5, -5, -5, -4, -3, 2]],
    [(-21,1),[-1, -2, 3, -4, -5, 6, 5, 7, -4, -6, -3, 5, 2, -4, 1, -3, -2, -4, -3, -5, 6, 5, -7, 4, -3, 5, 2, -4, -6, 3, -4, -5, -5, -5, -4]],
    [(-20,1),[-1, 2, -3, -4, -5, 6, 5, -4, 3, -2, 4, 1, -3, 5, -6, -7, -6, -5, 4, -3, -2, -3, -4, 5, -4, 6, 3, 7, -4, -5, -5, -4, -3, 2]],
    [(-19,1),[-1, 2, -3, -4, -3, 5, 4, -3, -2, 1, 3, 4, -5, -4, 6, -3, -5, 4, -3, 2, -3, -4, -3, 5, -2, -4, -6, 3]],
    [(-18,1),[-1, -2, -2, -3, 4, -3, -2, 1, 3, 2, -3, -4, 5, 4, 4, -3, -2, 3, 4, -5]],
    [(-17,1),[-1, 2, -3, -4, -5, -4, 3, -2, -4, 1, 3, 5, -4, 6, 5, 7, -4, 6, 3, -5, 2, 4, -3, -5, -4, 5, -6, -5, -7, -4, -6, 3, -2]],
    [(-16,1),[-1, 2, 3, -4, -3, 5, -6, 5, 4, -3, -2, 1, -3, 2, -3, -4, -4, -3, 4, 4, -5, 4, 6, -3, -2, -3, -4, -5, 4, 3, 3]],
    [(-15,1),[-1, 2, -3, -4, 5, -4, 6, -7, 6, -5, 4, 4, 3, -2, 4, 1, 5, -4, -6, 5, 7, -4, -8, 3, -7, 2, 6, -5, 4, -3, -5, -4, 5, -6, -5, 7, -4, -6, 8, 3, -5, -2, -4, 3]],
    [(-14,1),[-1, -2, -3, -4, 5, -4, 6, 3, 7, 2, -4, -8, 1, -3, -5, -7, 2, 4, -5, -6, -5, -4, -3, -4, 5, -4, 6, 3, 5, 7, -2, -4, -6, 8, -5, 4, 3, 4, 5, 4, 6, 4, -7, -5, -6, -5, -4]]]],
    [['o9_30634', 'K9_449'],
    [[(-18,1),[-1, 2, 3, -4, 5, -4, -3, -2, 4, 1, -3, -2, -4, -5, -4, 6, -3, 4, -3, -5, -3, -3, 4, 3, 3, 2, -3, 4, 5, 4, -6]],
    [(-17,1),[-1, 2, -3, 2, -4, 5, -4, 6, -4, -3, 4, -3, -5, -4, 3, -2, 1, 3, 4, -3, 5, 2, 4, -6, 4, -3, -5, 4, -3, -2]],
    [(-16,1),[-1, 2, -3, -4, -3, 5, -2, -6, 1, -3, 4, 3, -4, 3, 5, -4, 3, -2, 3, -4, -3, 4, -5, 4, 6, -5, 4, -3, 2]],
    [(-15,1),[-1, 2, 3, -4, 5, 6, 5, 4, -3, 5, -2, -6, 1, -3, 7, 4, -3, 5, 2, -4, 3, 5, -4, 6, 5, -4, -3, -2, 3, -4, -5, -6, -7]],
    [(-14,1),[-1, -2, -3, -4, -5, 4, -6, 5, -4, 3, 2, -4, 1, -3, 4, 4, -5, 4, 6, 3, -5, -2, 3, -4, 3, 5, 2]],
    [(-13,1),[-1, -2, 3, -2, -4, -3, 2, 1, 2, 2, -3, -2, 4, 3, -2, 3, 3, 3]],
    [(-12,1),[-1, -2, 3, -4, -5, -6, -5, -4, 3, 3, -2, 1, -3, -2, -3, 4, -3, 5, 2, 4, 6, -3, -5, -4, 5]],
    [(-11,1),[-1, 2, -3, 4, -3, -2, 1, -3, -2, -4, 5, 4, 6, 3, 4, 4, 4, 3, 5, -4, 3, 2, 3, -4, -3, 4, -5, 4, -6, -5]],
    [(-10,1),[-1, 2, -3, 4, 5, -6, -7, 8, -7, 9, 6, 10, -5, -4, 3, -5, -2, 4, 6, 1, 3, -5, -7, -8, -7, 9, 6, 8, -5, -4, -5, -6, -7, 6, -5, 4, -3, 2, -4, 3, -5, -4, 5, -6, 7, -8, 7, -9, -6, 8, -10, 5, 7, -9, 4, -8, -3, 7, -2, -6, -7]]]]]

In [3]:

    for data in branching_sets:
        K=snappy.Manifold(data[0][1])
        print('We consider the knot:',data[0][1],'=',data[0][0])
        for [slope,word] in data[1]:
            K.dehn_fill(slope)
            print(K)
            B=snappy.Link(braid_closure=word).exterior()
            D=double_branched_cover(B)
            #print(K.homology(),D.homology())
            w=better_is_isometric_to(K,D,try_hard=True)
            print('Branching set is verified via SnapPy:',w)
            if w=='unclear':
                v=search_for_combinatorial_equivalence(K,D,index_M=1,index_N=1)
                if v==False:
                    v=search_for_combinatorial_equivalence(K,D,index_M=2,index_N=1)
                if v==False:
                    v=search_for_combinatorial_equivalence(K,D,index_M=1,index_N=2)
                print('Branching set is verified via regina:',v)
        print('------')

    We consider the knot: K8_201 = t09847
    K8_201(-22,1)
    Branching set is verified via SnapPy: True
    K8_201(-21,1)
    Branching set is verified via SnapPy: True
    K8_201(-20,1)
    Branching set is verified via SnapPy: True
    K8_201(-19,1)
    Branching set is verified via SnapPy: unclear
    Branching set is verified via regina: True
    K8_201(-18,1)
    Branching set is verified via SnapPy: unclear
    Branching set is verified via regina: True
    K8_201(-17,1)
    Branching set is verified via SnapPy: True
    K8_201(-16,1)
    Branching set is verified via SnapPy: True
    K8_201(-15,1)
    Branching set is verified via SnapPy: True
    K8_201(-14,1)
    Branching set is verified via SnapPy: True
    ------
    We consider the knot: K9_449 = o9_30634
    K9_449(-18,1)
    Branching set is verified via SnapPy: True
    K9_449(-17,1)
    Branching set is verified via SnapPy: True
    K9_449(-16,1)
    Branching set is verified via SnapPy: True
    K9_449(-15,1)
    Branching set is verified via SnapPy: True
    K9_449(-14,1)
    Branching set is verified via SnapPy: unclear
    Branching set is verified via regina: True
    K9_449(-13,1)
    Branching set is verified via SnapPy: True
    K9_449(-12,1)
    Branching set is verified via SnapPy: True
    K9_449(-11,1)
    Branching set is verified via SnapPy: True
    K9_449(-10,1)
    Branching set is verified via SnapPy: True
    ------

Next, we create alphabetical braid words.

In [4]:

    for data in branching_sets:
        K=snappy.Manifold(data[0][1])
        #print(K)
        for [slope,word] in data[1]:
            print(slope,braid_word_to_letters(word))
        print('------')

    (-22, 1) AbCDEfeDcBdaCeFGFEdCBCDeDfcgDEEEEDCb
    (-21, 1) ABcDEfegDFCebDaCBDCEfeGdCebDFcDEEED
    (-20, 1) AbCDEfeDcBdaCeFGFEdCBCDeDfcgDEEDCb
    (-19, 1) AbCDCedCBacdEDfCEdCbCDCeBDFc
    (-18, 1) ABBCdCBacbCDeddCBcdE
    (-17, 1) AbCDEDcBDaceDfegDfcEbdCEDeFEGDFcB
    (-16, 1) AbcDCeFedCBaCbCDDCddEdfCBCDEdcc
    (-15, 1) AbCDeDfGfEddcBdaeDFegDHcGbfEdCEDeFEgDFhcEBDc
    (-14, 1) ABCDeDfcgbDHaCEGbdEFEDCDeDfcegBDFhEdcdedfdGEFED
    ------
    (-18, 1) AbcDeDCBdaCBDEDfCdCECCdccbCdedF
    (-17, 1) AbCbDeDfDCdCEDcBacdCebdFdCEdCB
    (-16, 1) AbCDCeBFaCdcDceDcBcDCdEdfEdCb
    (-15, 1) AbcDefedCeBFaCgdCebDceDfeDCBcDEFG
    (-14, 1) ABCDEdFeDcbDaCddEdfcEBcDceb
    (-13, 1) ABcBDCbabbCBdcBccc
    (-12, 1) ABcDEFEDccBaCBCdCebdfCEDe
    (-11, 1) AbCdCBaCBDedfcdddceDcbcDCdEdFE
    (-10, 1) AbCdeFGhGifjEDcEBdfacEGHGifhEDEFGfEdCbDcEDeFgHgIFhJegIdHCgBFG
    ------